from django.forms import forms
import re
import ast
from blacklist.models import APK
from datetime import datetime
import numpy as np
from scipy.stats import entropy
from model.models import APKInfo



def calculate_string_entropy(s):
    # 统计字符频率
    char_counts = np.array([s.count(c) for c in set(s)])
    char_probs = char_counts / char_counts.sum()

    # 计算信息熵
    entropy_value = entropy(char_probs)
    return entropy_value

def get_validdate(date_str):
    tmp_date=date_str.split(' to ')
    date_format = "%Y-%m-%d"
    date1 = datetime.strptime( tmp_date[0], date_format)
    date2 = datetime.strptime( tmp_date[1], date_format)
    delta = (date2 - date1).days
    return delta

class APKInfoForm:

    def __init__(self,apk_filename,activities,package,permissions,app_name,version_name,version_code,hash_algo,serial_number,
            contents_der,issuer,md5,sha1,sha256,validity_period,signature_algo,intent,icon_url,apk_size,folder_size):
        self.apk_filename=apk_filename#
        self.activities=activities#
        self.permissions=permissions#
        self.package=package#
        self.app_name=app_name#
        self.version_name=version_name#
        self.version_code=version_code
        self.hash_algo=hash_algo#
        self.serial_number=serial_number#
        self.contents_der=contents_der#
        self.issuer=issuer#
        self.md5=md5#
        self.sha1=sha1#
        self.sha256=sha256#
        self.validity_period=validity_period#
        self.signature_algo=signature_algo#
        self.intent=intent#
        self.icon_url=icon_url#
        self.apk_size=apk_size
        self.folder_size=folder_size


        # 处理特征
        self.permission_num=len(self.permissions)
        self.activities_num=len(self.activities)
        self.intents_num=len(self.intent)
        self.validdates=get_validdate(validity_period)
        self.entropy_value=calculate_string_entropy(package)
        self.ratio_before_and_after_decompression=folder_size//apk_size
        self.point_count=package.count('.')
        uppercase_count = sum(1 for char in package if char.isupper())
        self.proportions_of_capital_letters=uppercase_count/len(package)
        lowercase_count = sum(1 for char in package if char.islower())
        self.proportions_of_lowercase_letters=lowercase_count/len(package)
        self.package_len=len(package)
        self.avg_len_beteew_point=package.count('.')/len(package)
        self.issuer_len=len(issuer)
        self.contents_der_len=len(contents_der)
        self.hash_algo_md5  = 0
        self.hash_algo_sha1  = 0
        self.hash_algo_sha256  = 0
        self.hash_algo_sha384  = 0
        self.hash_algo_sha512  = 0
        self.signature_algo_dsa=0
        self.signature_algo_rsassa_pkcs1v15=0

        if hash_algo == 'md5' :
            self.hash_algo_md5 = 1
        elif hash_algo == 'sha1' :
            self.sha1=1
        elif hash_algo == 'sha256' :
            self.sha256=1
        elif hash_algo == 'sha384' :
            self.sha384=1
        else:
            self.sha512=1

        if signature_algo == 'dsa' :
           self.signature_algo_dsa=1
        else:
           self.signature_algo_rsassa_pkcs1v15=1


    # 模型更新需要修改
    def get_info(self):
        list_ret = []
        list_ret.append(self.version_code)
        list_ret.append(self.serial_number)
        list_ret.append(self.apk_size)
        list_ret.append(self.folder_size)
        list_ret.append(self.activities_num)
        list_ret.append(self.validdates)
        list_ret.append(self.intents_num)
        list_ret.append(self.entropy_value)
        list_ret.append(self.ratio_before_and_after_decompression)
        list_ret.append(self.point_count)
        list_ret.append(self.proportions_of_capital_letters)
        list_ret.append(self.proportions_of_lowercase_letters)
        list_ret.append(self.package_len)
        list_ret.append(self.avg_len_beteew_point)
        list_ret.append(self.issuer_len)
        list_ret.append(self.contents_der_len)
        list_ret.append(self.signature_algo_dsa)
        list_ret.append(self.signature_algo_rsassa_pkcs1v15)
        list_ret.append(self.hash_algo_md5)
        list_ret.append(self.hash_algo_sha1)
        list_ret.append(self.hash_algo_sha256)
        list_ret.append(self.hash_algo_sha384)
        list_ret.append(self.hash_algo_sha512)
        return list_ret

    def form2apkinfo(self):
        apk_info = APKInfo(
            apk_filename=self.apk_filename,
            activities=self.activities,
            package=self.package,
            permissions=self.permissions,
            app_name=self.app_name,
            version_name=self.version_name,
            version_code=self.version_code,
            hash_algo=self.hash_algo,
            serial_number=self.serial_number,
            contents_der=self.contents_der,
            issuer=self.issuer,
            md5=self.md5,
            sha1=self.sha1,
            sha256=self.sha256,
            validity_period=self.validity_period,
            signature_algo=self.signature_algo,
            intent=self.intent,
            icon_url=self.icon_url,
            apk_size=self.apk_size,
            folder_size=self.folder_size,
            permission_num=self.permission_num,
            activities_num=self.activities_num,
            intents_num=self.intents_num,
            validdates=self.validdates,
            entropy_value=self.entropy_value,
            ratio_before_and_after_decompression=self.ratio_before_and_after_decompression,
            point_count=self.point_count,
            proportions_of_capital_letters=self.proportions_of_capital_letters,
            proportions_of_lowercase_letters=self.proportions_of_lowercase_letters,
            package_len=self.package_len,
            avg_len_beteew_point=self.avg_len_beteew_point,
            issuer_len=self.issuer_len,
            contents_der_len=self.contents_der_len,
            hash_algo_md5=self.hash_algo_md5,
            hash_algo_sha1=self.hash_algo_sha1,
            hash_algo_sha256=self.hash_algo_sha256,
            hash_algo_sha384=self.hash_algo_sha384,
            hash_algo_sha512=self.hash_algo_sha512,
            signature_algo_dsa=self.signature_algo_dsa,
            signature_algo_rsassa_pkcs1v15=self.signature_algo_rsassa_pkcs1v15
        )
        apk_info.save()